"""
微信消息模块，用于发送微信消息
"""
import time
from typing import List, Dict, Any, Optional

from src.utils.logger import logger
from src.wechat.login import wechat_login


class WeChatMessage:
    """微信消息类，用于发送微信消息"""
    
    def __init__(self):
        """初始化微信消息类"""
        self._error_count = 0  # 错误计数器
        self._last_reset_time = time.time()  # 上次重置时间
        
        # 从配置文件中读取是否启用严格消息确认
        from src.utils.config import config_manager
        self.strict_message_confirmation = config_manager.get_value("wechat", "strict_message_confirmation", False)
    
    def _reset_wechat_instance(self) -> bool:
        """重置微信实例和wxauto库状态"""
        try:
            logger.info("开始重置微信实例...")
            
            # 保存当前微信窗口状态
            was_visible = wechat_login.is_logged_in
            
            # 重置wxauto实例
            wechat_login.wx_instance = None
            wechat_login.login_detected = False
            
            # 重新导入wxauto模块（强制重新加载）
            try:
                import importlib
                import sys
                if 'wxauto' in sys.modules:
                    importlib.reload(sys.modules['wxauto'])
                    logger.info("已重新加载wxauto模块")
            except Exception as e:
                logger.error(f"重新加载wxauto模块失败: {e}")
            
            # 重新初始化微信实例
            if was_visible:
                success = wechat_login.check_login()
                if success:
                    logger.info("微信实例重置成功")
                    self._error_count = 0  # 重置错误计数
                    self._last_reset_time = time.time()  # 更新重置时间
                    return True
                else:
                    logger.error("微信实例重置后登录失败")
                    return False
            
            logger.info("微信实例重置完成")
            self._error_count = 0  # 重置错误计数
            self._last_reset_time = time.time()  # 更新重置时间
            return True
        except Exception as e:
            logger.error(f"重置微信实例失败: {e}")
            return False
        
    def send_text(self, to_user: str, content: str) -> bool:
        """
        发送文本消息
        
        Args:
            to_user: 接收人
            content: 消息内容
            
        Returns:
            bool: 是否成功发送
        """
        # 检查是否需要自动重置微信实例
        current_time = time.time()
        hours_since_reset = (current_time - self._last_reset_time) / 3600
        
        # 如果错误计数过高或超过12小时未重置，自动重置微信实例
        if self._error_count >= 5 or hours_since_reset > 12:
            logger.warning(f"检测到错误计数({self._error_count})过高或超过12小时未重置({hours_since_reset:.1f}小时)，自动重置微信实例")
            self._reset_wechat_instance()
        
        try:
            # 检查微信是否已登录
            if not wechat_login.check_login():
                logger.error("微信未登录，无法发送消息")
                self._error_count += 1
                return False
            
            # 确保使用最新的微信实例
            wx_instance = wechat_login.wx_instance
            if not wx_instance:
                logger.error("微信实例无效")
                self._error_count += 1
                return False
            
            # 处理消息内容，替换可能导致问题的特殊字符
            processed_content = content
            if "..." in processed_content:
                processed_content = processed_content.replace("...", "…")  # 使用省略号Unicode字符替换
            
            # 发送消息 - 第一次尝试
            return self._try_send_message(wx_instance, to_user, processed_content)
            
        except Exception as e:
            logger.error(f"发送消息异常: {e}")
            self._error_count += 1
            return False
    
    def _try_send_message(self, wx_instance, to_user: str, content: str, is_retry: bool = False) -> bool:
        """
        尝试发送消息并验证发送状态
        
        Args:
            wx_instance: 微信实例
            to_user: 接收人
            content: 消息内容
            is_retry: 是否是重试发送
            
        Returns:
            bool: 是否成功发送
        """
        prefix = "重试后" if is_retry else ""
        
        try:
            # 先与联系人聊天，再发送消息
            result = wx_instance.ChatWith(to_user)
            if not result:
                logger.error(f"{prefix}找不到联系人: {to_user}")
                self._error_count += 1
                return False
            
            # 发送消息
            wx_instance.SendMsg(content)
            
            # 添加发送确认机制
            try:
                # 增加等待时间，让消息有足够时间发送并更新到聊天记录
                time.sleep(2)
                
                # 尝试多次获取最近的消息记录
                max_attempts = 3
                for attempt in range(max_attempts):
                    # 尝试获取最近的消息记录
                    recent_msgs = wx_instance.GetAllMessage()
                    
                    # 调试日志
                    if recent_msgs and isinstance(recent_msgs, list) and len(recent_msgs) > 0:
                        logger.debug(f"获取到{len(recent_msgs)}条消息记录")
                        
                        # 检查最新的消息是否就是我们刚发送的内容
                        # 微信消息是倒序排列的，最新的消息在最后几条
                        msg_found = False
                        
                        # 只检查最后3条消息
                        check_range = min(3, len(recent_msgs))
                        last_msgs = recent_msgs[-check_range:]
                        
                        for msg in last_msgs:
                            msg_content = ""
                            if isinstance(msg, str):
                                msg_content = msg
                            elif hasattr(msg, 'content'):
                                msg_content = msg.content
                                
                            # 记录日志，便于调试
                            logger.debug(f"检查消息内容: {msg_content}")
                            
                            # 使用完整内容匹配
                            if content.strip() == msg_content.strip():
                                msg_found = True
                                break
                            # 备用方案：如果完整匹配失败，检查消息内容是否包含我们发送的内容
                            elif content.strip() in msg_content.strip():
                                msg_found = True
                                break
                        
                        if msg_found:
                            logger.info(f"{prefix}已确认消息成功发送到: {to_user}")
                            self._error_count = 0  # 重置错误计数
                            return True
                    
                    # 如果不是最后一次尝试，等待一段时间后再试
                    if attempt < max_attempts - 1:
                        logger.info(f"第{attempt+1}次尝试未能确认消息，等待后再次尝试...")
                        time.sleep(1)  # 等待1秒后再次尝试
                
                # 如果所有尝试都失败
                if is_retry:
                    logger.warning(f"{prefix}发送可能失败：经过{max_attempts}次尝试，仍无法在最近消息中找到刚发送的内容")
                    self._error_count += 1
                    return False
                
                # 如果是首次尝试，根据配置决定是否严格验证
                if self.strict_message_confirmation:
                    logger.warning(f"严格消息确认已启用：经过{max_attempts}次尝试，无法确认消息发送成功，视为发送失败")
                    self._error_count += 1
                    return False
                else:
                    # 非严格模式，假定消息已发送成功
                    logger.warning(f"经过{max_attempts}次尝试，无法在消息记录中确认，但假定消息已发送到: {to_user}")
                    logger.warning("提示: 请检查消息是否实际发送成功，可能需要手动验证")
                    self._error_count = 0  # 不增加错误计数
                    return True
            except Exception as e:
                logger.warning(f"{prefix}验证消息发送状态时出错: {e}")
                
                # 如果是首次尝试，根据配置决定是否严格验证
                if not is_retry:
                    if self.strict_message_confirmation:
                        logger.warning(f"严格消息确认已启用：验证消息发送状态失败，视为发送失败")
                        self._error_count += 1
                        return False
                    else:
                        # 非严格模式，假定消息已发送成功
                        logger.warning(f"验证失败但假定消息已发送到: {to_user}，请手动检查")
                        self._error_count = 0
                        return True
                
                return False
                
        except Exception as e:
            logger.error(f"{prefix}发送消息异常: {e}")
            
            # 如果是首次尝试，尝试重置微信实例并重试
            if not is_retry:
                # 记录错误
                self._error_count += 1
                
                # 检查是否是特定错误
                error_str = str(e).lower()
                if "invalid literal for int()" in error_str or "find control timeout" in error_str:
                    logger.warning("检测到微信操作特定错误，尝试重置微信实例")
                    if self._reset_wechat_instance():
                        # 重置成功后重试一次
                        try:
                            # 获取新的微信实例
                            wx_instance = wechat_login.wx_instance
                            if not wx_instance:
                                logger.error("重置后微信实例仍然无效")
                                return False
                            
                            # 尝试使用另一种方式处理消息内容
                            processed_content = content
                            if "..." in processed_content:
                                processed_content = processed_content.replace("...", "..")
                            
                            # 重试发送
                            return self._try_send_message(wx_instance, to_user, processed_content, is_retry=True)
                            
                        except Exception as retry_e:
                            logger.error(f"重置后重试发送消息异常: {retry_e}")
                            return False
                else:
                    logger.warning(f"发送消息异常，但不进行重试: {e}")
                    return False
            
            self._error_count += 1
            return False
    
    def get_messages(self, chat_name: Optional[str] = None) -> List[Dict[str, Any]]:
        """
        获取聊天消息
        
        Args:
            chat_name: 聊天对象名称，如果为None则获取当前聊天窗口消息
            
        Returns:
            List[Dict[str, Any]]: 消息列表
        """
        try:
            # 检查微信是否已登录
            if not wechat_login.check_login():
                logger.error("微信未登录，无法获取消息")
                return []
            
            # 确保使用最新的微信实例
            wx_instance = wechat_login.wx_instance
            if not wx_instance:
                logger.error("微信实例无效")
                return []
            
            # 如果指定了聊天对象，则先切换到该聊天窗口
            if chat_name:
                result = wx_instance.ChatWith(chat_name)
                if not result:
                    logger.error(f"找不到聊天对象: {chat_name}")
                    return []
            
            # 获取消息
            try:
                messages = wx_instance.GetAllMessage()
                if messages:
                    # 转换消息格式为统一的字典格式
                    formatted_messages = []
                    for msg in messages:
                        # 如果msg已经是Message对象，则提取关键信息
                        if hasattr(msg, 'content'):
                            formatted_messages.append({
                                'content': msg.content,
                                'type': getattr(msg, 'type', 'text'),
                                'time': getattr(msg, 'time', ''),
                                'from': getattr(msg, 'from', ''),
                                'raw': msg
                            })
                        # 如果msg是字符串，则直接添加
                        elif isinstance(msg, str):
                            formatted_messages.append({
                                'content': msg,
                                'type': 'text',
                                'time': '',
                                'from': '',
                                'raw': msg
                            })
                        # 其他情况，尝试转换为字典
                        else:
                            try:
                                formatted_messages.append({
                                    'content': str(msg),
                                    'type': 'unknown',
                                    'time': '',
                                    'from': '',
                                    'raw': msg
                                })
                            except:
                                pass
                    
                    return formatted_messages
                else:
                    logger.info(f"未获取到聊天消息")
                    return []
            except Exception as e:
                logger.error(f"获取消息异常: {e}")
                return []
        except Exception as e:
            logger.error(f"获取消息异常: {e}")
            return []


# 单例实例
wechat_message = WeChatMessage()